package com.nexgo.payment.trans.ecbalance;

import android.support.annotation.NonNull;

import com.nexgo.payment.aop.annotation.TransCondition;
import com.nexgo.payment.trans.TransFlow;
import com.nexgo.common.ByteUtils;
import com.nexgo.data.entity.RecvData;
import com.nexgo.oaf.apiv3.SdkResult;
import com.nexgo.oaf.apiv3.emv.EmvAlgorithmTypeEnum;
import com.nexgo.oaf.apiv3.emv.EmvChannelTypeEnum;
import com.nexgo.oaf.apiv3.emv.EmvProcessResultEntity;
import com.nexgo.oaf.apiv3.emv.EmvTransDataEntity;
import com.nexgo.oaf.apiv3.emv.EmvTransFlowEnum;
import com.nexgo.payment.App;
import com.nexgo.payment.R;
import com.nexgo.payment.action.ActionResult;
import com.nexgo.payment.action.ActionStep;
import com.nexgo.payment.constrant.CardMode;
import com.nexgo.payment.constrant.PreferencesConstants;
import com.nexgo.payment.constrant.SysConstant;
import com.nexgo.payment.constrant.TransType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.entity.CardInfo;
import com.nexgo.payment.entity.TransData;
import com.nexgo.payment.trans.AbsTransPresenter;
import com.nexgo.payment.util.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;

import java8.util.Optional;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 电子现金 余额查询
 * <p>
 * Created by wanghongyang on 2017/8/31.
 */
@TransCondition
@TransFlow(checkFreePinBySetting = false, checkNeedElectronicSignature = false, checkNeedReceipt = false)
public class EcBalancePresenter extends AbsTransPresenter implements EcBalanceContract.Presenter {
    private Logger mLog = LoggerFactory.getLogger(EcBalancePresenter.class.getSimpleName());

    private EcBalanceContract.View mView;

    public EcBalancePresenter(@NonNull EcBalanceContract.View view, @NonNull DataSource repository) {
        super(view, repository);
        mView = checkNotNull(view);
        mView.setPresenter(this);
    }

    @Override
    protected TransData getTransData() {
        TransData transData = new TransData();
        transData.setTransType(TransType.EC_BALANCE);
        return transData;
    }

    @Override
    protected EmvTransDataEntity getEmvTransData(EmvChannelTypeEnum channelType) {
        EmvTransDataEntity emvTransData = new EmvTransDataEntity();
        emvTransData.setChannelType(channelType);
        emvTransData.setB9C((byte) 0x00);
        emvTransData.setTransAmt("000000000000");
        //支持电子现金
        emvTransData.setIsDefaultEC(true);
        emvTransData.setIsSupportEC(true);
        emvTransData.setTermId(mRepository.getParamValue(PreferencesConstants.TERMINAL_ID));
        emvTransData.setMerId(mRepository.getParamValue(PreferencesConstants.MERCHANT_ID));
        emvTransData.setMerName(mRepository.getParamValue(PreferencesConstants.MERCHANT_NAME));
        emvTransData.setTransDate(new SimpleDateFormat("yyMMdd", SysConstant.LOCALE).format(new Date()));
        emvTransData.setTransTime(new SimpleDateFormat("hhmmss", SysConstant.LOCALE).format(new Date()));
        emvTransData.setTraceNo(mRepository.getParamValue(PreferencesConstants.TRACE_NUMBER));
        emvTransData.setAlgType("1".equals(mRepository.getParamValue(PreferencesConstants.EMV_SUPPORT_SM2)) ?
                EmvAlgorithmTypeEnum.SM2 : EmvAlgorithmTypeEnum.RSA);
        if (channelType == EmvChannelTypeEnum.FROM_PICC) {
            emvTransData.setProcType(EmvTransFlowEnum.QPASS);
        } else {
            emvTransData.setProcType(EmvTransFlowEnum.FULL);
            emvTransData.setChannelType(EmvChannelTypeEnum.FROM_ICC);
        }
        emvTransData.setIsForceOnline(false);
        return  emvTransData;
    }

    @Override
    protected void onFirstAction() {
        postMainThread(() -> mView.showReadCard(mTransData));
    }

    @Override
    public void importActionResult(ActionResult actionResult) {
        Object data = actionResult.getData();
        ActionStep step = (ActionStep) actionResult.getAction().getActionStep();
        int ret = actionResult.getRet();
        mLog.debug("curr action step {} ret {}", step, actionResult.getRet());
        //成功处理进行处理，否则让父类处理
        if (ret == ActionResult.SUCC) {
            switch (step) {
                case QUERY_RESP:
                    postMainThread(() -> mView.quitTrans());
                    break;
                default:
                    break;
            }
        }
        super.importActionResult(actionResult);
    }

    @Override
    protected void readCardNext(Object data) {
        CardInfo cardInfo = (CardInfo) data;
        mTransData.setCardMode(cardInfo.getCardMode());
        //判断用卡方式
        if (CardMode.INSERT.equals(mTransData.getCardMode())) {
            mTransData.setCardMode(CardMode.INSERT);
            int result = mSdkEmvHandler.emvGetEcBalance(EmvChannelTypeEnum.FROM_ICC, new EmvProcessListener());
            if (result == SdkResult.Success) {
                postMainThread(() -> mView.setWaitingIndicator(true, App.sContext.getString(R.string.card_reading),App.sContext.getString(R.string.do_not_remove_card)));
            } else {
                postMainThread(() -> mView.showTransFailed());
            }
        } else if (CardMode.TAP.equals(mTransData.getCardMode())) {
            mTransData.setCardMode(CardMode.TAP);
            int result = mSdkEmvHandler.emvGetEcBalance(EmvChannelTypeEnum.FROM_PICC, new EmvProcessListener());
            if (result == SdkResult.Success) {
                postMainThread(() -> mView.setWaitingIndicator(true, App.sContext.getString(R.string.card_reading),App.sContext.getString(R.string.do_not_remove_card)));
            } else {
                postMainThread(() -> mView.showTransFailed());
            }
        } else {
            postMainThread(() -> mView.showTransFailed());
        }
    }

    @Override
    protected void onTransSuccess(RecvData recvData, EmvProcessResultEntity emvResult) {
        Optional.ofNullable(emvResult)
                .filter(entity -> entity != null)
                .map(entity -> entity.getEcBalance())
                .map(bytes -> StringUtils.leftPad(ByteUtils.byteArray2HexString(bytes), 12, '0'))
                .ifPresentOrElse(s -> {
                    mLog.debug("amount = {}", s);
                    mTransData.setAmount(s);
                    //跳转到显示结果界面
                    postMainThread(() -> mView.showQueryResp(mTransData));
                }, () -> postMainThread(() -> mView.showTransFailed()));
    }

}
